use sea_orm::{sea_query::SimpleExpr, ConnectionTrait, DbConn, DbErr, DynIden};

use crate::{
    model::{Filter, GenTable},
    JsonMap,
};

pub struct Mutation;

#[allow(dead_code, unused)]
impl Mutation {
    pub async fn create_table(db: &DbConn, table: &GenTable) -> Result<(), DbErr> {
        let table_sql = table.table_create_statement();
        let state = db.get_database_backend().build(&table_sql);
        let s = db.execute(state).await?;
        return Ok(());
    }

    pub async fn insert(
        db: &DbConn,
        table: &GenTable,
        data: &JsonMap,
    ) -> Result<(), DbErr> {
        let mut sql = table.insert(data);
        let state = db.get_database_backend().build(&sql);
    
        let r = db.execute(state).await?;
        
        println!("===11 {:?}", r);
        return Ok(());
    }

    pub async fn delete_by_id<V>(db: &DbConn, table: &GenTable, id: V) -> Result<(), DbErr>
    where
        V: Into<SimpleExpr>,
    {
        let sql = table.delete_by_id(id);
        let state = db.get_database_backend().build(&sql);
        db.execute(state).await?;
        return Ok(());
    }

    pub async fn update_by_id<V>(
        db: &DbConn,
        table: &GenTable,
        id: V,
        value: &JsonMap,
    ) -> Result<(), DbErr>
    where
        V: Into<SimpleExpr>,
    {
        let sql = table.update_by_id(id, value);
        let state = db.get_database_backend().build(&sql);
        db.execute(state).await?;
        return Ok(());
    }

    pub async fn update(
        db: &DbConn,
        table: &GenTable,
        value: &serde_json::Map<String, serde_json::Value>,
        filters: Vec<Filter>,
    ) -> Result<(), DbErr> {
        let mut sql = sea_query::Query::update();
        sql.table(table);
        for (k, v) in value {
            if let Some(col) = table.get_column(k.as_str()) {
                sql.value(Into::<DynIden>::into(col), col.type_().expr_of(&v).unwrap());
            }
        }
        filters.iter().for_each(|f| {
            sql.cond_where(f.get_cond());
        });
        let state = db.get_database_backend().build(&sql);
        db.execute(state).await?;
        return Ok(());
    }
}
